//
//  TestSerialTaskViewController.swift
//  testTaskQueue
//
//  Created by kingdee on 2021/2/5.
//

import UIKit

@objcMembers class TestSerialTaskViewController: UIViewController {
    
    var manager = HHSerialTaskManager(strictSerial: true)
    var concurrentManager = HHConcurrentTaskManager(concurrentCount: 4)
    
    static var task1Int: Int = 0
    static var task2Int: Int = 0
    static var task3Int: Int = 0
    static var task4Int: Int = 0
    static var task5Int: Int = 0
    static var task6Int: Int = 0
    static var task7Int: Int = 0
    static var task8Int: Int = 0
    static var task9Int: Int = 0
    static var task0Int: Int = 0
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.view.backgroundColor = UIColor.white
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        testSerialTask()
//        testConcurrentTask()
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        
        manager.clearResource()
        
        Self.task1Int = 0
        Self.task2Int = 0
        Self.task3Int = 0
        Self.task4Int = 0
        Self.task5Int = 0
        Self.task6Int = 0
        Self.task7Int = 0
        Self.task8Int = 0
        Self.task9Int = 0
        Self.task0Int = 0
    }
    
    // MARK: - conurrent task
    
    fileprivate func testConcurrentTask() {
        
        let task5 = concurrentManager.creatTask({ (callBack) in
            DispatchQueue.global().async {
                sleep(1)
                if Self.task5Int == 10 {
                    debugPrint("\(Date()) task5 run...success")
                    callBack(true)
                } else {
                    debugPrint("\(Date()) task5 run...failed")
                    callBack(false)
                }
                Self.task5Int += 1
            }
        }, overRetry: { callBack in
            debugPrint("\(Date()) task5 failure")
            callBack()
        }, retryMaxCount: 7, retryTimeStrategy: [1, 3, 5, 9, 11])
        
        let task6 = concurrentManager.creatTaskNotPromiseSucces { callBack in
            DispatchQueue.global().async {
                sleep(2)
                if Self.task6Int == 0 {
                    debugPrint("\(Date()) task6 run...success")
                    callBack(true)
                } else {
                    debugPrint("\(Date()) task6 run...failed")
                    callBack(false)
                }
                Self.task6Int += 1
            }
        }
        
        let task7 = concurrentManager.creatTaskFailedRetryAtOnce({ callBack in
            DispatchQueue.global().async {
                sleep(3)
                if Self.task7Int == 2 {
                    debugPrint("\(Date()) task7 run...success")
                    callBack(true)
                } else {
                    debugPrint("\(Date()) task7 run...failed")
                    callBack(false)
                }
                Self.task7Int += 1
            }
            
        }, overRetry: { callBack in
            
        }, retryMaxCount: 3)
        
        let task8 = concurrentManager.creatTaskFailedRetryAtOnce({ callBack in
            DispatchQueue.global().async {
                sleep(2)
                if Self.task8Int == 2 {
                    debugPrint("\(Date()) task8 run...success")
                    callBack(true)
                } else {
                    debugPrint("\(Date()) task8 run...failed")
                    callBack(false)
                }
                Self.task8Int += 1
            }
        }, overRetry: { callBack in
            
        }, retryMaxCount: 3)
        
        let task9 = concurrentManager.creatTask({ (callBack) in
            DispatchQueue.global().async {
                sleep(3)
                if Self.task9Int == 10 {
                    debugPrint("\(Date()) task9 run...success")
                    callBack(true)
                } else {
                    debugPrint("\(Date()) task9 run...failed")
                    callBack(false)
                }
                Self.task9Int += 1
            }
        }, overRetry: { callBack in
            debugPrint("\(Date()) task9 failure")
            callBack()
        }, retryMaxCount: 3, retryTimeStrategy: [1, 3, 5, 9, 11])
        
        let task0 = concurrentManager.creatTask({ (callBack) in
            DispatchQueue.global().async {
                sleep(0)
                if Self.task0Int == 2 {
                    debugPrint("\(Date()) task0 run...success")
                    callBack(true)
                } else {
                    debugPrint("\(Date()) task0 run...failed")
                    callBack(false)
                }
                Self.task0Int += 1
            }
        }, overRetry: { callBack in
            debugPrint("\(Date()) task0 failure")
            callBack()
        }, retryMaxCount: 3, retryTimeStrategy: [1, 3, 5, 9, 11])
        
        concurrentManager.addTaskToRun(taskIdentifier: task5)
        concurrentManager.addTaskToRun(taskIdentifier: task6)
        concurrentManager.addTaskToRun(taskIdentifier: task7)
        concurrentManager.addTaskToRun(taskIdentifier: task8)
        concurrentManager.addTaskToRun(taskIdentifier: task9)
        concurrentManager.addTaskToRun(taskIdentifier: task0)
        
        //        manager.startService()
        DispatchQueue.global().async {
            self.concurrentManager.startService()
        }
    }
    
    // MARK: - serial task
    fileprivate func testSerialTask() {
        
        let task1 = manager.creatTask({ (callBack) in
            DispatchQueue.global().async {
                sleep(2)
                if Self.task1Int == 6 {
                    debugPrint("\(Date()) task1 run...success")
                    callBack(true)
                } else {
                    debugPrint("\(Date()) task1 run...failed")
                    callBack(false)
                }
                Self.task1Int += 1
            }
        }, overRetry: {[weak self] callBack in
            debugPrint("\(Date()) task1 failure")
//            self?.manager.cancelAllTask()
            callBack()
        }, retryMaxCount: 5, retryTimeStrategy: [1, 3, 5, 9, 11])
        
        let task2 = manager.creatTaskNotPromiseSucces { callBack in
            DispatchQueue.global().async {
                sleep(3)
                if Self.task2Int == 0 {
                    debugPrint("\(Date()) task2 run...success")
                    callBack(true)
                } else {
                    debugPrint("\(Date()) task2 run...failed")
                    callBack(false)
                }
                Self.task2Int += 1
            }
        }
        
        let task3 = manager.creatTaskFailedRetryAtOnce({ callBack in
            DispatchQueue.global().async {
                sleep(2)
                if Self.task3Int == 2 {
                    debugPrint("\(Date()) task3 run...success")
                    callBack(true)
                } else {
                    debugPrint("\(Date()) task3 run...failed")
                    callBack(false)
                }
                Self.task3Int += 1
            }
            
        }, overRetry: { callBack in
            callBack()
        }, retryMaxCount: 3)
        
        let task4 = manager.creatTaskFailedRetryAtOnce({ callBack in
            DispatchQueue.global().async {
                sleep(2)
                if Self.task4Int == 2 {
                    debugPrint("\(Date()) task4 run...success")
                    callBack(true)
                } else {
                    debugPrint("\(Date()) task4 run...failed")
                    callBack(false)
                }
                Self.task4Int += 1
            }
        }, overRetry: { callBack in
            callBack()
        }, retryMaxCount: 3)
        
        manager.addTaskToRun(taskIdentifier: task1)
        manager.addTaskToRun(taskIdentifier: task2)
        manager.addTaskToRun(taskIdentifier: task3)
        manager.addTaskToRun(taskIdentifier: task4)
        
        //        manager.startService()
        DispatchQueue.global().async {
            self.manager.startService()
        }

    }
    
}
